/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "MultiFileAndroid.h"
#include "File.h"
#include "Memory.h"
#include <NoCopy.h>
#include <filesystem/File.h>
#include <logs/Log.h>
#include <AutoPtr.h>
#include <Gluck.h>
#include <vector>
#include <system/Environment.h>


#ifdef ANDROID_NDK
#include <android/log.h>
#endif


namespace liba
{
namespace resource
{

MultiFile::MultiFile(const std::string & apk_filename)
:	apk_archive(0)
{
	__android_log_print(ANDROID_LOG_INFO, "MultiFile", "apk_filename = %s", apk_filename.c_str());

	std::string apk_fullPath = (filesystem::String("%app_path%").c_str() + filesystem::String(apk_filename)).c_str();

	__android_log_print(ANDROID_LOG_INFO, "MultiFile", "apk_fullPath = %s", apk_fullPath.c_str());

	apk_archive = zip_open(apk_fullPath.c_str(), 0, NULL);
	if (!apk_archive)
	{
		return;
	}

	//Just for debug, print APK contents
	int numFiles = zip_get_num_files(apk_archive);
	for (int i=0; i<numFiles; i++) {
		const char* name = zip_get_name(apk_archive, i, 0);
//		if (name == NULL)
	//		logs::log()  << "Error reading zip file name at index: " << i << " error: " << zip_strerror(apk_archive);
//		else
//			logs::log()  << "file: " << name;
	}
}
	
MultiFile::~MultiFile()
{}
	
Resource * MultiFile::create_resource(const filesystem::String & fname)
{
	resource::Resource *res = 0;
	std::string basePath = "";
	std::string nameHD = Environment::instance()->isLargeScreen() ? "hd" : "";
	std::string nameLite = Environment::instance()->isLiteVersion() ? "lite" : "";
	std::string locale = Environment::instance()->getLanguage().c_str();

	__android_log_print(ANDROID_LOG_INFO, "MultiFile", "nameHD = %s", nameHD.c_str());
	__android_log_print(ANDROID_LOG_INFO, "MultiFile", "nameLite = %s", nameLite.c_str());
	__android_log_print(ANDROID_LOG_INFO, "MultiFile", "locale = %s", locale.c_str());

	std::string name;

	if ( ! nameLite.empty() )
	{
		name = basePath + nameLite + "/" + fname;
		res = create_resource_from_file(name);
		if ( res )
		{
			__android_log_print(ANDROID_LOG_INFO, "MultiFile", "name = %s", name.c_str());
			return res;
		}
	}


	if ( ! nameHD.empty() )
	{
		if ( ! locale.empty() )
		{
			name = basePath + nameHD + "/" + locale + "/" + fname;
			res = create_resource_from_file(name);
			if ( res )
			{
				__android_log_print(ANDROID_LOG_INFO, "MultiFile", "name = %s", name.c_str());
				return res;
			}
		}

		name = basePath + nameHD + "/" + fname;
		res = create_resource_from_file(name);
		if ( res )
		{
			__android_log_print(ANDROID_LOG_INFO, "MultiFile", "name = %s", name.c_str());
			return res;
		}
	}

	if ( ! locale.empty() )
	{
		name = basePath + locale + "/" + fname;
		res = create_resource_from_file(name);
		if ( res )
		{
			__android_log_print(ANDROID_LOG_INFO, "MultiFile", "name = %s", name.c_str());
			return res;
		}
	}

	name = basePath + fname;
	res = create_resource_from_file(name);

	return res;
}


Resource * MultiFile::create_resource_from_file(const filesystem::String & name)
{
	//TODO: possible to optimize here by having custom ZipResource
	struct zip_stat stat;
	zip_stat_init(&stat);


	__android_log_print(ANDROID_LOG_INFO, "MultiFile", "name = %s", name.c_str());

	if(zip_stat(apk_archive, name.c_str(), ZIP_FL_UNCHANGED, &stat))
	{
		logs::log() << "Error getting zip_stat for: " << name.c_str();
		__android_log_print(ANDROID_LOG_ERROR, "MultiFile", "Error getting zip_stat for: %s", name.c_str());
		return 0;
	}

	zip_file* file = zip_fopen(apk_archive, name.c_str(), 0);
	if (!file)
	{
		logs::log() << "Error opening from APK: " << name.c_str();
		__android_log_print(ANDROID_LOG_ERROR, "MultiFile", "Error opening from APK: %s", name.c_str());
		return 0;
	}

	std::vector<char> data;
	data.resize(stat.size);

	zip_fread(file, &(data.front()), stat.size);
	zip_fclose(file); file = 0;

	resource::Memory * res = new resource::Memory(data);	
	return res;
}

} // namespace resource
} // namespace liba

